Skip to content

WIP: nordic: add nRF54L15 and nRF54LM20 platform support and full-duplex I2S loopback - #11224

Draft
lgirdwood wants to merge 6 commits into
thesofproject:mainfrom
lgirdwood:feature/nordic-sof-port
Draft

lgirdwood wants to merge 6 commits into
thesofproject:mainfrom
lgirdwood:feature/nordic-sof-port

Conversation

@lgirdwood

Copy link
Copy Markdown
Member

Summary

This draft PR introduces Sound Open Firmware (SOF) platform support for Nordic Semiconductor nRF54L Series development boards (ARM Cortex-M33 with FPU @ 128 MHz):

  • Nordic nRF54LM20-DK (PCA10184): High-speed USB UAC2 ingress and hardware I2S/TDM Master Tx/Rx.
  • Nordic nRF54L15-DK (PCA10156): Hardware I2S20 Slave Full-Duplex Echo with parametric EQ and DRC processing.

Companion Zephyr driver changes are in lgirdwood/zephyr#2 on branch feature/nordic-dai-port.


Key Changes

  1. Nordic Platform Support (src/platform/nordic/):

    • Added platform definitions, interrupt registration, mailbox stubs, and clocks for nRF54L15 and nRF54LM20.
    • Added board configurations and devicetree overlays for nrf54l15dk_nrf54l15_cpuapp and nrf54lm20dk_nrf54lm20b_cpuapp.
  2. I2S Hardware Audio Driver Component (src/audio/i2s_audio.c):

    • Implemented SOF host endpoint for Zephyr I2S subsystem supporting both i2s_nrfx (nRF54L15) and i2s_nrf_tdm (nRF54LM20).
    • Real-time periodic telemetry reporting frame rates and buffer overruns/underruns.
  3. Static Audio Pipeline Topologies:

    • nRF54LM20 (nrf54lm20_pipeline_def.c):
      • Pipeline 1: USB_PB $\to$ VOL_PB $\to$ EQ_PB $\to$ DRC_PB $\to$ I2S_TX (TDM Master Tx)
      • Pipeline 2: I2S_RX (TDM Master Rx) $\to$ LEVEL_RX $\to$ USB_CAP
    • nRF54L15 (nrf54l15_pipeline_def.c):
      • Pipeline 1: I2S_RX (I2S20 Slave Rx) $\to$ VOL_PB $\to$ EQ_PB $\to$ DRC_PB $\to$ I2S_TX (I2S20 Slave Tx) full-duplex loopback.
  4. nRF54L15 Interconnect Pin Multiplexing:

    • Routed i2s20 peripheral to GPIO Port 1 pins (P1.11 SCK, P1.12 LRCK, P1.09 SDIN, P1.08 SDOUT) to comply with nRF54L15 peripheral domain interconnect silicon constraints.
  5. Static Pipeline Loader (static_pipeline_loader.c):

    • Enhanced sof_static_pipeline_trigger() to resolve pipe->sink_comp when triggering capture pipelines where scheduler component is not at the source.

Live Hardware Verification

Verified with physical jumper cables between nRF54LM20-DK Header P3 (Master) and nRF54L15-DK Header P1 (Slave):

  • BCLK: LM20 P1.23 $\to$ L15 P1.11
  • LRCK / FSYNC: LM20 P1.24 $\to$ L15 P1.12
  • SDOUT $\to$ SDIN: LM20 P1.30 $\to$ L15 P1.09
  • SDIN $\leftarrow$ SDOUT: LM20 P1.31 $\leftarrow$ L15 P1.08
  • GND: Header P3 GND $\to$ Header P1 GND

Both boards continuously stream full-duplex 48 kHz stereo 16-bit PCM at exactly 48,000 frames/second with 0 overruns:

  • LM20-DK: Streamed $>2,064,000$ frames TX/RX at $+48,000$ frames/s.
  • L15-DK: Streamed $>5,088,000$ frames TX/RX at $+48,000$ frames/s.

@lgirdwood
lgirdwood force-pushed the feature/nordic-sof-port branch 3 times, most recently from 58c5263 to 1dd21ce Compare October 15, 2026 16:38
@lgirdwood
lgirdwood force-pushed the feature/nordic-sof-port branch from 1dd21ce to fc42158 Compare November 10, 2026 16:06
@lgirdwood
lgirdwood requested a balanced review from Copilot November 10, 2026 16:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

5 open issues
What changed in this PR

This draft PR adds Zephyr-only SOF support for Nordic nRF54L series boards, including new platform bring-up pieces, static pipeline topologies, and new host-like components for USB/I2S/BT audio bridging.

Changes:

  • Added Nordic platform layer (clock init, mailbox definitions, platform init) and board-specific static pipeline topologies for nRF54L15 and nRF54LM20.
  • Introduced new “host endpoint” style audio components: usb_audio, i2s_audio, bt_audio plus a Bluetooth service helper and a Nordic-focused static pipeline controller.
  • Expanded Zephyr build integration (CMake/Kconfig/syscall guards), UUID registry entries, and minor runtime fixes in existing modules/DAI code.
File Description
zephyr/​lib/​alloc.c Adds Nordic heap sizing/allocation path for Zephyr builds.
zephyr/​include/​sof/​lib/​cpu.h Gates syscall declarations on CONFIG_USERSPACE for full Zephyr app builds.
zephyr/​include/​rtos/​cache.h Adjusts default cache line size logic to include Nordic.
zephyr/​CMakeLists.txt Adds Nordic platform selection/build wiring and generated include dir.
uuid-registry.txt Adds UUID registry entries for new audio components.
src/​platform/​nordic/​platform.c Implements Nordic platform init + IPC/mailbox boot-ready handling.
src/​platform/​nordic/​nrf54lm20_pipeline_def.c Adds static topology for LM20 (USB↔I2S + capture loop).
src/​platform/​nordic/​nrf54l15_pipeline_def.c Adds static topology for L15 full-duplex I2S echo.
src/​platform/​nordic/​lib/​clk.c Adds minimal clock table/init for Nordic.
src/​platform/​nordic/​include/​platform/​trace/​trace.h Adds Nordic platform trace header stub.
src/​platform/​nordic/​include/​platform/​platform.h Adds Nordic platform constants and limits.
src/​platform/​nordic/​include/​platform/​lib/​pm_runtime.h Adds Nordic PM runtime header stub.
src/​platform/​nordic/​include/​platform/​lib/​memory.h Adds Nordic heap sizing + cache alignment macros.
src/​platform/​nordic/​include/​platform/​lib/​mailbox.h Adds mailbox layout and stubbed SW reg accessors.
src/​platform/​nordic/​include/​platform/​lib/​dma.h Adds Nordic DMA header stub (0 DMACs).
src/​platform/​nordic/​include/​platform/​lib/​dai.h Adds Nordic DAI header including Zephyr DAI glue.
src/​platform/​nordic/​include/​platform/​lib/​clk.h Adds Nordic clock constants + init prototype.
src/​platform/​nordic/​include/​platform/​drivers/​interrupt.h Adds Nordic interrupt header stub.
src/​platform/​Kconfig Adds PLATFORM_NORDIC + nRF54L15/nRF54LM20 choice.
src/​include/​user/​debug_stream_slot.h Adds non-userspace fallback mapping for syscall symbol.
src/​include/​sof/​schedule/​ll_schedule_domain.h Gates syscall API on CONFIG_USERSPACE for full Zephyr app.
src/​include/​sof/​schedule/​dp_schedule.h Adds non-userspace fallbacks and gates syscalls on CONFIG_USERSPACE.
src/​include/​sof/​lib_manager.h Gates syscall API on CONFIG_USERSPACE for full Zephyr app.
src/​include/​sof/​lib/​vregion.h Only includes Zephyr syscall header when userspace is enabled.
src/​include/​sof/​lib/​dai-zephyr.h Adds non-userspace fallbacks for Zephyr DAI device accessors.
src/​include/​sof/​ipc/​msg.h Gates IPC-related syscalls on CONFIG_USERSPACE for full Zephyr app.
src/​include/​sof/​ipc/​ipc_reply.h Gates reply syscall on CONFIG_USERSPACE for full Zephyr app.
src/​include/​sof/​audio/​usb_audio.h Adds public header for USB audio component bridge API.
src/​include/​sof/​audio/​pipeline/​sof_static_pipeline.h Adds higher-level static pipeline control/status API.
src/​include/​sof/​audio/​module_adapter/​module/​generic.h Gates module syscalls on CONFIG_USERSPACE in full Zephyr app.
src/​include/​sof/​audio/​i2s_audio.h Adds public header for I2S audio component stats API.
src/​include/​sof/​audio/​bt_service.h Adds public BT service control/status API.
src/​include/​sof/​audio/​bt_audio.h Adds public BT audio component bridge API.
src/​include/​ipc4/​notification.h Gates IPC4 notification syscalls on CONFIG_USERSPACE.
src/​include/​ipc4/​handler.h Gates IPC4 handler syscalls on CONFIG_USERSPACE.
src/​audio/​usb_audio.c Implements USB audio ring-buffer bridge component (usb_audio).
src/​audio/​pipeline/​sof_static_pipeline.c Adds Nordic-focused static pipeline orchestration + UAC2 glue.
src/​audio/​pipeline/​CMakeLists.txt Builds sof_static_pipeline.c for Nordic.
src/​audio/​module_adapter/​module_adapter_ipc4.c Initializes module sinks/sources if missing before prepare.
src/​audio/​i2s_audio.c Implements Zephyr I2S bridge component (i2s_audio).
src/​audio/​drc/​drc_riscv.c Switches byte count/channel parameter types to size_t/unsigned.
src/​audio/​drc/​drc_log.c Forces DRC module registration reference when built-in.
src/​audio/​drc/​drc_arm.c Switches byte count/channel parameter types to size_t/unsigned.
src/​audio/​dai-zephyr.c Nordic-specific DAI reset/trigger behavior adjustments.
src/​audio/​bt_service.c Adds BT service thread + Nordic LM20/L15 connect/scan logic.
src/​audio/​bt_audio.c Implements BT audio ring-buffer bridge component (bt_audio).
src/​audio/​Kconfig Adds Kconfigs for new USB/BT/I2S bridge components.
src/​audio/​CMakeLists.txt Adds build rules for new audio components.
scripts/​cmake/​misc.cmake Treats full Zephyr app builds as “Zephyr” in helper macro.
app/​src/​usbd_init.c Adds USB device stack init helper (with Teensy vendor requests).
app/​src/​sample_usbd.h Adds sample USBD helper header.
app/​src/​main.c Initializes UAC2 ops, USB stack, BT service, and static pipelines for Nordic.
app/​boards/​nrf54lm20dk_nrf54lm20b_cpuapp.overlay Adds LM20 UAC2 + TDM pinmux overlay and alias for I2S node.
app/​boards/​nrf54lm20dk_nrf54lm20b_cpuapp.conf Adds LM20 feature set config (UAC2 HS, TDM, modules).
app/​boards/​nrf54l15dk_nrf54l15_cpuapp.overlay Adds L15 I2S20 pinmux overlay and alias for I2S node.
app/​boards/​nrf54l15dk_nrf54l15_cpuapp.conf Adds L15 feature set config (I2S NRFX slave, modules).
app/​Kconfig Pulls in sample USBD Kconfig and rsource Zephyr Kconfig when needed.
app/​CMakeLists.txt Links SOF libraries into the Zephyr app and adds USBD init source.
Kconfig.sof Always includes Zephyr log Kconfig rather than gating on module build.

Review effort: Lite

Comment thread app/src/usbd_init.c Outdated
Comment on lines +231 to +263
static struct net_buf *teensy_peek_to_host(const struct usbd_context *const ctx,
const struct usb_setup_packet *const setup)
{
uint32_t addr = (setup->wIndex << 16) | setup->wValue;
uint16_t len = MIN(setup->wLength, 64);
if (!len) return NULL;
struct net_buf *buf = usbd_ep_ctrl_data_in_alloc(ctx, len);
if (!buf) return NULL;
net_buf_add_mem(buf, (const void *)addr, len);
return buf;
}

static int teensy_poke_to_dev(const struct usbd_context *const ctx,
const struct usb_setup_packet *const setup,
const struct net_buf *const buf)
{
ARG_UNUSED(ctx);
uint32_t addr = (setup->wIndex << 16) | setup->wValue;
if (buf && buf->len > 0) {
if (setup->wLength == 1) {
*(volatile uint8_t *)addr = buf->data[0];
} else if (setup->wLength == 2) {
uint16_t val;
memcpy(&val, buf->data, 2);
*(volatile uint16_t *)addr = val;
} else if (setup->wLength == 4) {
uint32_t val;
memcpy(&val, buf->data, 4);
*(volatile uint32_t *)addr = val;
}
}
return 0;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed all Teensy and ESP32 vendor requests, peek/poke routines, and hardware diagnostics entirely from usbd_init.c, eliminating arbitrary memory access risks and keeping the USB stack standard.

Comment thread src/audio/i2s_audio.c Outdated

dev->ipc_config = *config;

iad = rzalloc(SOF_MEM_FLAG_USER, sizeof(*iad));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed to allocate with SOF_MEM_FLAG_KERNEL consistent with kernel context and other host components.

Comment thread src/audio/i2s_audio.c
Comment on lines +217 to +223
void *block;
for (int i = 0; i < 8; i++) {
if (k_mem_slab_alloc(&i2s_tx_slab, &block, K_NO_WAIT) == 0) {
memset(block, 0, I2S_BLOCK_SIZE);
i2s_write(s_i2s_dev, block, I2S_BLOCK_SIZE);
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: now checks i2s_write() return value during TX priming and frees the slab buffer on write failure to prevent memory leaks.

Comment thread src/audio/i2s_audio.c
}
k_mem_slab_free(&i2s_rx_slab, rx_block);
s_i2s_stats.rx_frames += frames_to_copy;
} else {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: ensures rx_block is released back to i2s_rx_slab on all error and size-mismatch paths.

Comment thread src/audio/usb_audio.c Outdated
if (!g_capture_data || !g_capture_data->active || !g_capture_data->started) {
return false;
}
return g_capture_data->ring.count >= bytes;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: usb_audio_has_capture_data() now acquires ring->lock before inspecting ring->count to prevent race conditions on SMP/preemption.

@lgirdwood lgirdwood left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be split into zephyr patches and sof patches. Each per feature. The zephyr patches can go on my fork and be referred via a temp west patch

Comment thread src/audio/drc/drc_arm.c
const struct sof_drc_params *p,
int nbyte,
int nch)
size_t nbyte,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be a separate patch

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split into a dedicated commit: audio: drc: align drc_arm and drc_riscv parameter types with drc_algorithm.h.

Comment thread src/audio/drc/drc_log.c Outdated
EXPORT_SYMBOL(log_dynamic_drc);
#endif

#if !CONFIG_COMP_DRC_MODULE

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a separate patch.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted this change; the __used reference was a temporary workaround that broke non-Zephyr host testbench builds. DRC symbols are properly linked without it.

{
struct processing_module *mod = comp_mod(dev);

if (!mod->num_of_sources && !mod->num_of_sinks)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be its own patch

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split into a dedicated commit: audio: module_adapter: initialize sinks and sources in prepare if unpopulated.

@@ -0,0 +1,805 @@
// SPDX-License-Identifier: BSD-3-Clause

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should be reusing the existing static pipeline logic.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored to directly reuse the upstream static_pipeline_loader.c and static_pipeline_uac2.c infrastructure (sof_static_topology_init, sof_static_pipeline_trigger, sof_static_kcontrol_set_by_uac2, etc.). Purged all non-Nordic (ESP32-P4 and Teensy 4.1) hardware manipulation and register code.


if (g_status.playback_active || g_status.capture_active) {
s_sof_diag_cnt++;
#if defined(CONFIG_PLATFORM_ESP32P4)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like it should be under LOG_DBG ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: replaced periodic diagnostics with LOG_DBG and removed the ESP32 register dump entirely.

…rithm.h

Update drc_update_detector_average and drc_compress_output in drc_arm.c
and drc_riscv.c to take size_t nbyte and unsigned int nch, matching
the prototypes declared in drc_algorithm.h.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
…opulated

In static audio pipeline configurations where module sources and sinks
have not yet been enumerated via dynamic IPC4 binding commands, trigger
module_adapter_update_sinks_sources() during module_adapter_sink_src_prepare()
if both num_of_sources and num_of_sinks are zero.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
…ication support

- Guard Zephyr syscall headers and prototypes with CONFIG_USERSPACE checks
  in SOF headers so non-userspace platforms build without stub generation.
- Fix Doxygen group closing tag in dai-zephyr.h to ensure valid group scope
  independent of CONFIG_USERSPACE definition.
- Support CONFIG_SOF_FULL_ZEPHYR_APPLICATION in is_zephyr() macro.
- Hoist version and uuid registry target generation before subdirectory processing.
- Add UUID entries for usb_audio and bt_audio in uuid-registry.txt.
- Define heapmem sizing for CONFIG_PLATFORM_NORDIC.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Temporarily point the Zephyr project remote to https://github.com/lgirdwood/zephyr
at revision fcf26c58845d3cf24348d273e119879a699e4fc9 (branch feature/nordic-dai-port)
which contains the i2s_nrfx and i2s_nrf_tdm DAI driver enhancements for
Nordic nRF54L Series boards while upstream Zephyr PR reviews are pending.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
- Add USB Audio Class 2 (UAC2) host endpoint component (usb_audio.c)
  with spinlock-protected buffer count checking.
- Add Bluetooth LE Audio streaming endpoint and service (bt_audio.c, bt_service.c).
- Add Zephyr I2S host endpoint supporting full-duplex PCM streaming (i2s_audio.c),
  allocating private context with SOF_MEM_FLAG_KERNEL, error handling on TX
  priming buffer submission with slab release, and RX slab free on error/mismatch.
- Add static pipeline runner and runtime control dispatcher (sof_static_pipeline.c)
  reusing upstream static pipeline topology and UAC2 kcontrol APIs.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
…l-duplex I2S loopback

Add full platform support and static audio topologies for Nordic nRF54L15
(PCA10156) and nRF54LM20 (PCA10184) running on Zephyr RTOS:

- src/platform/nordic: platform boot, clock tree (128 MHz), mailbox structures,
  Zephyr timer-based Low-Latency scheduler domain (zephyr_domain_init).
- static topologies:
  * nRF54LM20: Pipeline 1 (USB_PB -> VOL -> EQ -> DRC -> I2S_TX) master playback,
    Pipeline 2 (I2S_RX -> LEVEL -> USB_CAP) master loopback capture.
  * nRF54L15: Pipeline 1 (I2S_RX -> VOL -> EQ -> DRC -> I2S_TX) slave full-duplex echo.
- app/boards: devicetree overlays and Kconfig configurations for:
  * nrf54l15dk_nrf54l15_cpuapp: i2s20 slave interconnect mapped to Port 1
    (P1.11 BCLK, P1.12 LRCK, P1.09 SDIN, P1.08 SDOUT).
  * nrf54lm20dk_nrf54lm20b_cpuapp: High-speed USB UAC2 device and i2s_nrf_tdm
    master (P1.23 BCLK, P1.24 FSYNC, P1.30 SDOUT, P1.31 SDIN).
- app/src/usbd_init.c: Standard USB UAC2 device stack initialization without
  non-standard peek/poke vendor requests.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
@lgirdwood
lgirdwood force-pushed the feature/nordic-sof-port branch from fc42158 to f583f24 Compare November 10, 2026 22:55
@lgirdwood

Copy link
Copy Markdown
Member Author

The PR has been reorganized according to review feedback:

  1. Zephyr / SOF Separation:

    • Zephyr DAI and peripheral driver changes are maintained on lgirdwood/zephyr on branch feature/nordic-dai-port (commit fcf26c58845d3cf24348d273e119879a699e4fc9).
    • A dedicated temporary manifest patch is included in this series (west: manifest: temporarily reference Zephyr DAI port for Nordic) pointing to that fork until Zephyr upstream merges.
  2. Clean Per-Feature Patch Series:
    The SOF branch is rebased on latest main and cleanly split into 6 focused commits:

    • audio: drc: align drc_arm and drc_riscv parameter types with drc_algorithm.h
    • audio: module_adapter: initialize sinks and sources in prepare if unpopulated
    • zephyr: build: guard userspace syscall declarations and add full application support
    • west: manifest: temporarily reference Zephyr DAI port for Nordic
    • audio: host: add USB, Bluetooth, and I2S static pipeline endpoints
    • platform: nordic: add nRF54L15 and nRF54LM20 platform support and full-duplex I2S loopback
  3. Addressed All Review Comments:

    • DRC: Fixed parameter types in drc_arm.c and drc_riscv.c to match drc_algorithm.h (size_t nbyte, unsigned int nch). Reverted drc_log.c hack to origin/main (fixes host testbench).
    • Doxygen / Headers: Fixed Doxygen group closure error in dai-zephyr.h by keeping /** @}*/ outside CONFIG_USERSPACE.
    • Static Pipeline & USB Cleanup: Purged all ESP32/Teensy hardware registers, clock switching code, and peek/poke vendor requests from sof_static_pipeline.c and usbd_init.c. Refactored pipeline management to leverage upstream static_pipeline_loader APIs.
    • I2S Audio: Changed i2s_audio allocation to SOF_MEM_FLAG_KERNEL, added error handling and slab free on i2s_write() during TX priming, and guaranteed rx_block slab release on all error and size-mismatch paths.
    • USB Audio: Added k_spin_lock protection to usb_audio_has_capture_data() to prevent races on SMP/preemption.
    • Zephyr Module Integration: Used EXTRA_ZEPHYR_MODULES in app/CMakeLists.txt to enable native module discovery via zephyr/module.yml, removing duplicate rsource in app/Kconfig.
  4. Hardware Verification:

    • Verified clean builds of build_lm20 and build_l15.
    • Flashed physical nRF54LM20-DK (Master Tx) and nRF54L15-DK (Slave Rx) over J-Link, confirming stable full-duplex 48 kHz streaming on serial consoles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants